inline bool regprofile::is_open() const
	{ return hbase != 0; }

template <typename T> 
inline void regprofile::get0(string const & path, T & value) const
{
	if ((std::istringstream(get<std::string>(path)) >> value).fail())
		throw parse_error(string("Registry value '") + path + "' could not be converted to requested type");
}

template <> 
inline void regprofile::get0<std::string>(string const & path, string & value) const
	{ get_string(path, value); }

template <> 
inline void regprofile::get0<reg_blob>(string const & path, reg_blob & value) const
	{ get_blob(path, value); }

template <> 
inline void regprofile::get0<long long>(string const & path, long long & value) const
	{ get_llint(path, value); }

#define get_integer(type) \
	template <>  \
	inline void regprofile::get0<type>(string const & path, type & value) const { \
		long long i; \
		get_llint(path, i); \
		value = i; \
	}

get_integer(char)
get_integer(unsigned char)
get_integer(short)
get_integer(unsigned short)
get_integer(int)
get_integer(unsigned int)
get_integer(long)
get_integer(unsigned long)
get_integer(unsigned long long)

#undef get_integer

template <> 
inline void regprofile::get0<bool>(string const & path, bool & value) const {
	long long i;
	get_llint(path, i);
	value = i != 0;
}

template <> 
inline void regprofile::get0<double>(string const & path, double & value) const
	{ get_double(path, value); }

template <> 
inline void regprofile::get0<float>(string const & path, float & value) const {
	double d;
	get_double(path, d);
	value = d;
}

template <typename T> 
inline T regprofile::get(string const & path) const
{
	T value;
	get0(path, value);
	return value;
}

template <typename T> 
inline void regprofile::get(string const & path, T & value, const T & def) const
{
	try {
		if (!is_open())
			value = def;
		else
			get0(path, value);
	}
	catch (error const &) {
		value = def;
	}
}

template <typename T> 
inline T regprofile::get(string const & path, const T & def) const
{
	try {
		if (!is_open())
			return def;
		return get<T>(path);
	}
	catch (error const &) {
		return def;
	}
}

template <typename T> 
inline bool regprofile::query(string const & path, T & value) const
{
	try {
		get0(path, value); 
		return true;
	}
	catch (not_found const &) 
		{ return false;	}
	catch (access_denied const &) 
		{ return false;	}
}

template <typename T> 
inline bool regprofile::query(string const & path, T & value, const T & def) const
{
	try {
		if (!is_open()) {
			value = def;
			return false;
		}
		get0(path, value); 
		return true;
	}
	catch (not_found const &) {
		value = def;
		return false;
	}
	catch (access_denied const &) {
		value = def;
		return false;
	}
}

template <typename T> 
inline void regprofile::set(string const & path, T const & value)
{
	std::ostringstream o;
	o << value;
	set_string(path, o.str());
}

template <> 
inline void regprofile::set<std::string>(string const & path, std::string const & value)
	{ set_string(path, value); }

template <> 
inline void regprofile::set<reg_blob>(string const & path, reg_blob const & value)
	{ set_blob(path, value); }

#define set_integer(type) \
	template <> \
	inline void regprofile::set<type>(string const & path, type const & value) \
		{ set_int(path, value); }

set_integer(char)
set_integer(unsigned char)
set_integer(short)
set_integer(unsigned short)
set_integer(int)
set_integer(unsigned int)
set_integer(long)
set_integer(unsigned long)

#undef set_integer

template <>
inline void regprofile::set<bool>(string const & path, bool const & value)
	{ set_int(path, value ? 1 : 0); }

template <> 
inline void regprofile::set<long long>(string const & path, long long const & value)
	{ set_llint(path, value); }

template <> 
inline void regprofile::set<unsigned long long>(string const & path, unsigned long long const & value)
	{ set_llint(path, value); }

inline bool regprofile::erase(string const & path)
{
	try {
		remove(path);
		return true;
	}
	catch (not_found const &) {
		return false;
	}
}

